package com.acme.bankapp.tcp.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import com.acme.CommandHandler;
import com.acme.bankapp.exceptions.BankException;

public class BankServer {
	private ServerSocket providerSocket;
	private Socket connection = null;
	private ObjectOutputStream out;
	private ObjectInputStream in;
	private String cleintCommand;
	private CommandHandler commandHandler;

	public BankServer(CommandHandler commandHandler) {
	    this.commandHandler = commandHandler;
	}

	public void run() throws BankException {
		try {
			// 1. creating a server socket
			providerSocket = new ServerSocket(2004, 10);

			// 2. Wait for connection
			System.out.println("server-log> Waiting for connection");
			connection = providerSocket.accept();
			System.out.println("server-log> Connection received from " + connection.getInetAddress().getHostName());

			// 3. get Input and Output streams
			out = new ObjectOutputStream(connection.getOutputStream());
			out.flush();
			in = new ObjectInputStream(connection.getInputStream());
			sendMessage("Connection successful");

			// 4. The two parts communicate via the input and output streams
			do {
				try {
				    cleintCommand = (String) in.readObject();
					System.out.println("client-to-server>" + cleintCommand);

					commandHandler.processCommand(cleintCommand);

					sendMessage("command executed");
				} catch (ClassNotFoundException classnot) {
					System.err.println("Data received in unknown format");
				}
			} while (!cleintCommand.equals(CommandHandler.CLOSE_CONNECTION));
		} catch (IOException ioException) {
			ioException.printStackTrace();
		} finally {
			// 4: Closing connection
			try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
                if (providerSocket != null) {
                    providerSocket.close();
                }
			} catch (IOException ioException) {
				ioException.printStackTrace();
			}
		}
	}

	private void sendMessage(final String msg) {
		try {
			out.writeObject(msg);
			out.flush();
			System.out.println("server-to-client>" + msg);
		} catch (IOException ioException) {
			ioException.printStackTrace();
		}
	}

}
